import pandas as pd
from openai import OpenAI
from sklearn.metrics import accuracy_score
import ollama

import numpy as np
import pandas as pd
from warnings import simplefilter
import streamlit as lit
import langroid.language_models as lm
import langroid as lr

simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
simplefilter(action="ignore", category=FutureWarning)
#ignore ValueError
simplefilter(action="ignore", category=ValueError)
API_key = 'apikey'
client = OpenAI(api_key=API_key)

# question = input('Enter the question you want to ask the model: ')


def openai_result(query, df):
    model = ai(API_key)

    sdf = SmartDataframe(df = df, config={"llm":model})
    try:
        response = sdf.chat(query+'If graphing, you must return a sentence: Graphing completed')
        return response
    except:
        return 'FAILED'
    
    
    


def local_llm_result(model,query,df):
    sdf = SmartDataframe(df=df, config={"llm": model,"save_logs": True, "conversational": False,"verbose":True})
    
    result = sdf.chat(query+'If graphing, you must return a sentence: Graphing completed')
    return result

def truth_value(df,query):
    result = eval(query)
    return result


if __name__ == '__main__':
    # initializations
    filename = 'data/cleaned_data.csv'
    df = pd.read_csv(filename, low_memory=False)

    # column_ids = [84, 101, 114, 166, 183, 187, 188, 190, 194, 199, 204, 206, 276]
    # column_names = df.columns[column_ids]
    # for col_name in column_names:
    #     if col_name in df.columns:
    #         df[col_name] = df[col_name].astype(str).replace('nan', 'NULL')
    
    


    # query construction
    # mode = input('Enter running mode: 0 is from file, 1 is manual')



    # print(result_llm)
    query_to_openai = 'I want you to be the prompt engingeer and edit the prompt I will give you based on the column I give you. Can you must replace the related content with the exact column name. To be remind about only return the edited content don\'t say something like here\'s the edited prompt, I only want the result. I want the prompt to be accuracy as well and envolve with all the necessary key words, try to use minimal calls to the columns. When calling column names put a quatation mark around the column name.'
    
    # query_to_openai += 'filepath:data/cleaned_data.csv'
    column_names = df.columns
    column_values = ''
    prohibited = ['CrashId']
    for col_name in df.columns:
        if col_name not in prohibited:
            column_values += col_name + ':' + ', '.join(map(str, df[col_name].unique())) + '\n'

    questions = []
    with open('questions.txt', 'r') as f:
        questions = f.readlines()
    for question in questions:
        query_to_openai += 'Column names:' + ', '.join(column_names)

        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {
                    "role": "system",
                    "content": query_to_openai
                },
                {
                    "role": "user",
                    "content": question 
                }
            ],
            temperature=0.7,
            max_tokens=1024,
            top_p=1
        )

        message = response.choices[0].message.content
        print("Edited prompt:", message)
        pre_prompting = 'I want you to generate code, use pandas functions as possible, keep code clean, a single dataframe named \'dfs\' is already defined. Do not define a function put everything down. Directly call on it. I only want the result, Do not graph anything:'
        # pre_prompting += ', '.join(column_names)
        message_to_execute = pre_prompting + message
        question = pre_prompting + question   

        # message += 'the data file name is'+filename
        # pre_prompt = 'I want you to repeat what I say:'
        # message = pre_prompt + message

        ### The result generation Factory:
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="llama3.1:latest")
            llama_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in llama_result:
                llama_result = 'FAILED'
        except:
            llama_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="deepseek-coder-v2:latest")
            deepseek_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in deepseek_result:
                deepseek_result = 'FAILED'
        except:
            deepseek_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="starcoder2:latest")
            starcoder_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in starcoder_result:
                starcoder_result = 'FAILED'
        except:
            starcoder_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="gemma2:27b")
            gemma_result = local_llm_result(model,message_to_execute,df)
            if 'Unfortunately' in gemma_result:
                gemma_result = 'FAILED'
        except:
            gemma_result = 'FAILED'
        try:
            chatgpt_result = openai_result(message_to_execute,df)
            if 'Unfortunately' in chatgpt_result:
                chatgpt_result = 'FAILED'
        except:
            chatgpt_result = 'FAILED'
        with open('results.csv', 'a') as f:
            f.write(f'{message_to_execute}\n{question}')
            f.write(f'{llama_result},{deepseek_result},{starcoder_result},{gemma_result},{chatgpt_result}\n')
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="llama3.1:latest")
            llama_result = local_llm_result(model,question,df)
            if 'Unfortunately' in llama_result:
                llama_result = 'FAILED'
        except:
            llama_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="deepseek-coder-v2:latest")
            deepseek_result = local_llm_result(model,question,df)
            if 'Unfortunately' in deepseek_result:
                deepseek_result = 'FAILED'
        except:
            deepseek_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="starcoder2:latest")
            starcoder_result = local_llm_result(model,question,df)
            if 'Unfortunately' in starcoder_result:
                starcoder_result = 'FAILED'
        except:
            starcoder_result = 'FAILED'
        try:
            model = LocalLLM(api_base="http://localhost:11434/v1", model="gemma2:27b")
            gemma_result = local_llm_result(model,question,df)
            if 'Unfortunately' in gemma_result:
                gemma_result = 'FAILED'
        except:
            gemma_result = 'FAILED'
        try:
            chatgpt_result = openai_result(question,df)
            if 'Unfortunately' in chatgpt_result:
                chatgpt_result = 'FAILED'
        except:
            chatgpt_result = 'FAILED'
        with open('results.csv', 'a') as f:
            f.write(f'{llama_result},{deepseek_result},{starcoder_result},{gemma_result},{chatgpt_result}\n')
            f.write('\n')
        ### End of factory

        
        

        